package com.changgou.order.service.impl;

import com.changgou.common.util.IdWorker;
import com.changgou.goods.feign.SkuFeign;
import com.changgou.order.dao.OrderItemMapper;
import com.changgou.order.dao.OrderMapper;
import com.changgou.order.pojo.Order;
import com.changgou.order.pojo.OrderItem;
import com.changgou.order.service.OrderService;
import com.changgou.user.feign.UserFeign;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import io.seata.spring.annotation.GlobalTransactional;
import org.springframework.amqp.AmqpException;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessagePostProcessor;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import tk.mybatis.mapper.entity.Example;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

@Service
public class OrderServiceImpl implements OrderService {

  @Autowired private OrderMapper orderMapper;

  /**
   * 删除订单号
   * @param  outtradeno 订单号 
   */
  @Override
  public void deleteOrder(String outtradeno) {
    /**
     * 查询订单状态
     */
    Order orders =  orderMapper.selectByPrimaryKey(outtradeno);
    // 逻辑删除
     orders.setIsDelete("1");
     orders.setUpdateTime(new Date());
     //支付订单
     orders.setPayStatus("2");
     //修改订单状态
    orderMapper.updateByPrimaryKeySelective(orders);
    // 库存回滚
    /**
     * 自己的大致实现的流程
     * 就是把订单表中的商品的数量得到，然后到gooos 中的tb_sku表中进行商品数量的相加
     * ----    前提时用户没有进行支付 ----
     * 这里通过feign远程调用
     *
     */

  }

  /**
   * 修改订单状态
   * @param outtradeno 订单号
   * @param paytime 支付时间
   * @param transactionid 交易流水号
   */
  @Override
  public void updateStatus(String outtradeno, String paytime, String transactionid) throws ParseException {
    //时间转换
    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
    Date patyDateTime = simpleDateFormat.parse(paytime);
    Order order = orderMapper.selectByPrimaryKey(outtradeno);

    // 修改订单
    order.setPayTime(patyDateTime);
    //在线支付
    order.setPayStatus("1");
    // 修改交易流水号
    order.setTransactionId(transactionid);
    //把数据更新到数据库中
     orderMapper.updateByPrimaryKeySelective(order);
  }

  /**
   * 查询全部列表
   *
   * @return
   */
  @Override
  public List<Order> findAll() {
    return orderMapper.selectAll();
  }

  /**
   * 根据ID查询
   *
   * @param id
   * @return
   */
  @Override
  public Order findById(String id) {
    return orderMapper.selectByPrimaryKey(id);
  }

  @Autowired private IdWorker idWorker;
  @Autowired private RedisTemplate redisTemplate;
  @Autowired
  private OrderItemMapper orderItemMapper;
  @Autowired
  private SkuFeign skuFeign;
  @Autowired
  private UserFeign userFeign;
  @Autowired
  private RabbitTemplate rabbitTemplate;
  /**
   * 增加
   *
   * @param order
   */
  @Override
  @GlobalTransactional // 开启分布式事务
  public void add(Order order) {
      //获取用户购物车的集合(d订单明细)
      List <OrderItem> orderItemList = new ArrayList<>();
    // 获取当前勾选的订单ID，需要下载的商品，将要下单的商品从购物车移除
    for (Long skuId: order.getSkuIds()) {
        //先添加
      Object object = redisTemplate.boundHashOps("Cart_heima").get(skuId);
      orderItemList.add((OrderItem) object);
      redisTemplate.boundHashOps("Cart_heima").delete(skuId);
    }
    // 订单添加一次
    order.setId(String.valueOf(idWorker.nextId())); //主键id
     //总数量
      int totalNum=0;
      // 总金额
      int totalMoney=0;
      //封装递减数据
      Map<String,Integer> decMap= new HashMap<>();
      for (OrderItem orderItem : orderItemList) {
          totalNum+=orderItem.getNum();
          totalMoney+=orderItem.getMoney();
          //订单的明细id
          orderItem.setId(String.valueOf(idWorker.nextId()));
          //订单明细所属的订单
          orderItem.setOrderId(order.getId());
          //是否退货
          orderItem.setIsReturn("0");
          //封装递减数据
        decMap.put(orderItem.getSkuId(), orderItem.getNum());

      }


      order.setCreateTime(new Date());//创建时间
      order.setUpdateTime(order.getCreateTime());//修改时间
      order.setSourceType("1");//订单来源
      order.setOrderStatus("0");//订单状态
      order.setPayStatus("0");//未支付


      order.setTotalNum(totalNum);//总数量
      order.setTotalMoney(totalMoney);//订单总金额
      order.setPayMoney(totalMoney);
      // 明细添加多次
      // insertSelective 选择性保存数据
      //insert 而insert则是不论你设置多少个字段，统一都要添加一遍，不论你设置几个字段，即使是一个。
    orderMapper.insertSelective(order);
    // 循环添加订单明细信息
    for (OrderItem orderItem : orderItemList) {
        orderItemMapper.insertSelective(orderItem);
      //
    }
    //商品数据递减
    skuFeign.decrCopunt(decMap);
    // 添加用户的积分
    userFeign.addPoints(1);
    // 输出订单创建的时间
    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    System.out.println("订单创建的时间是"+simpleDateFormat.format(new Date()));
    //发送延时消息
    rabbitTemplate.convertAndSend("orderDelayQueue", (Object) order.getId().toString(), new MessagePostProcessor() {

      @Override
      public Message postProcessMessage(Message message) throws AmqpException {
        //设置延时读取 10秒中
        message.getMessageProperties().setExpiration("10000");
        return message;
      }
    });
  }

  /**
   * 修改
   *
   * @param order
   */
  @Override
  public void update(Order order) {
    orderMapper.updateByPrimaryKey(order);
  }

  /**
   * 删除
   *
   * @param id
   */
  @Override
  public void delete(String id) {
    orderMapper.deleteByPrimaryKey(id);
  }

  /**
   * 条件查询
   *
   * @param searchMap
   * @return
   */
  @Override
  public List<Order> findList(Map<String, Object> searchMap) {
    Example example = createExample(searchMap);
    return orderMapper.selectByExample(example);
  }

  /**
   * 分页查询
   *
   * @param page
   * @param size
   * @return
   */
  @Override
  public Page<Order> findPage(int page, int size) {
    PageHelper.startPage(page, size);
    return (Page<Order>) orderMapper.selectAll();
  }

  /**
   * 条件+分页查询
   *
   * @param searchMap 查询条件
   * @param page 页码
   * @param size 页大小
   * @return 分页结果
   */
  @Override
  public Page<Order> findPage(Map<String, Object> searchMap, int page, int size) {
    PageHelper.startPage(page, size);
    Example example = createExample(searchMap);
    return (Page<Order>) orderMapper.selectByExample(example);
  }

  /**
   * 构建查询对象
   *
   * @param searchMap
   * @return
   */
  private Example createExample(Map<String, Object> searchMap) {
    Example example = new Example(Order.class);
    Example.Criteria criteria = example.createCriteria();
    if (searchMap != null) {
      // 订单id
      if (searchMap.get("id") != null && !"".equals(searchMap.get("id"))) {
        criteria.andEqualTo("id", searchMap.get("id"));
      }
      // 支付类型，1、在线支付、0 货到付款
      if (searchMap.get("payType") != null && !"".equals(searchMap.get("payType"))) {
        criteria.andEqualTo("payType", searchMap.get("payType"));
      }
      // 物流名称
      if (searchMap.get("shippingName") != null && !"".equals(searchMap.get("shippingName"))) {
        criteria.andLike("shippingName", "%" + searchMap.get("shippingName") + "%");
      }
      // 物流单号
      if (searchMap.get("shippingCode") != null && !"".equals(searchMap.get("shippingCode"))) {
        criteria.andLike("shippingCode", "%" + searchMap.get("shippingCode") + "%");
      }
      // 用户名称
      if (searchMap.get("username") != null && !"".equals(searchMap.get("username"))) {
        criteria.andLike("username", "%" + searchMap.get("username") + "%");
      }
      // 买家留言
      if (searchMap.get("buyerMessage") != null && !"".equals(searchMap.get("buyerMessage"))) {
        criteria.andLike("buyerMessage", "%" + searchMap.get("buyerMessage") + "%");
      }
      // 是否评价
      if (searchMap.get("buyerRate") != null && !"".equals(searchMap.get("buyerRate"))) {
        criteria.andLike("buyerRate", "%" + searchMap.get("buyerRate") + "%");
      }
      // 收货人
      if (searchMap.get("receiverContact") != null
          && !"".equals(searchMap.get("receiverContact"))) {
        criteria.andLike("receiverContact", "%" + searchMap.get("receiverContact") + "%");
      }
      // 收货人手机
      if (searchMap.get("receiverMobile") != null && !"".equals(searchMap.get("receiverMobile"))) {
        criteria.andLike("receiverMobile", "%" + searchMap.get("receiverMobile") + "%");
      }
      // 收货人地址
      if (searchMap.get("receiverAddress") != null
          && !"".equals(searchMap.get("receiverAddress"))) {
        criteria.andLike("receiverAddress", "%" + searchMap.get("receiverAddress") + "%");
      }
      // 订单来源：1:web，2：app，3：微信公众号，4：微信小程序  5 H5手机页面
      if (searchMap.get("sourceType") != null && !"".equals(searchMap.get("sourceType"))) {
        criteria.andEqualTo("sourceType", searchMap.get("sourceType"));
      }
      // 交易流水号
      if (searchMap.get("transactionId") != null && !"".equals(searchMap.get("transactionId"))) {
        criteria.andLike("transactionId", "%" + searchMap.get("transactionId") + "%");
      }
      // 订单状态
      if (searchMap.get("orderStatus") != null && !"".equals(searchMap.get("orderStatus"))) {
        criteria.andEqualTo("orderStatus", searchMap.get("orderStatus"));
      }
      // 支付状态
      if (searchMap.get("payStatus") != null && !"".equals(searchMap.get("payStatus"))) {
        criteria.andEqualTo("payStatus", searchMap.get("payStatus"));
      }
      // 发货状态
      if (searchMap.get("consignStatus") != null && !"".equals(searchMap.get("consignStatus"))) {
        criteria.andEqualTo("consignStatus", searchMap.get("consignStatus"));
      }
      // 是否删除
      if (searchMap.get("isDelete") != null && !"".equals(searchMap.get("isDelete"))) {
        criteria.andEqualTo("isDelete", searchMap.get("isDelete"));
      }

      // 数量合计
      if (searchMap.get("totalNum") != null) {
        criteria.andEqualTo("totalNum", searchMap.get("totalNum"));
      }
      // 金额合计
      if (searchMap.get("totalMoney") != null) {
        criteria.andEqualTo("totalMoney", searchMap.get("totalMoney"));
      }
      // 优惠金额
      if (searchMap.get("preMoney") != null) {
        criteria.andEqualTo("preMoney", searchMap.get("preMoney"));
      }
      // 邮费
      if (searchMap.get("postFee") != null) {
        criteria.andEqualTo("postFee", searchMap.get("postFee"));
      }
      // 实付金额
      if (searchMap.get("payMoney") != null) {
        criteria.andEqualTo("payMoney", searchMap.get("payMoney"));
      }
    }
    return example;
  }
}
